


#ifndef __QE_BACKTRACE_H__
#define __QE_BACKTRACE_H__



#include "qe_def.h"



#define QE_BACKTRACE_CALLS_DEPTH    (16)
#define QE_BACKTRACE_STACK_DEPTH    (32)



/* Cortex AArch32 */
#if defined(__arm__)
typedef struct
{
    qe_ubase r0;
    qe_ubase r1;
    qe_ubase r2;
    qe_ubase r3;
    qe_ubase r4;
    qe_ubase r5;
    qe_ubase r6;
    qe_ubase r7;
    qe_ubase r8;
    qe_ubase r9;
    qe_ubase r10;
    qe_ubase fp;    /* r11 */
    qe_ubase r12;   /* r12 */
    qe_ubase sp;    /* r13 */
    qe_ubase lr;    /* r14 */
    qe_ubase pc;    /* r15 */
} qe_backtrace_regs;
#endif

typedef struct
{
    char taskname[16];

    qe_bool is_main_stack;
    qe_bool is_on_fault;

    qe_backtrace_regs fault;
    qe_backtrace_regs frame;

    qe_ubase fp;
    qe_ubase stack_start;
    qe_ubase stack_size;

    qe_uint calls_depth;
    qe_ubase calls[QE_BACKTRACE_CALLS_DEPTH];

    qe_uint stack_depth;
    qe_uint stack[QE_BACKTRACE_STACK_DEPTH];

} qe_backtrace_info;


/* weak function @{ */
qe_ubase qe_task_stack_start(void);
qe_uint qe_task_stack_size(void);
qe_ubase qe_main_stack_start(void);
qe_uint qe_main_stack_size(void);
qe_ubase qe_text_start(void);
qe_uint qe_text_size(void);
char *qe_current_task_name(void);
/* }@ weak function */

void backtrace_data_abort(qe_ubase addr);
void backtrace_code_abort(qe_ubase addr);
void backtrace_div_abort(void);

void qe_backtrace_init(qe_ubase stack_start, qe_uint stack_size,
    qe_ubase code_start, qe_uint code_size);

void qe_backtrace_call_stack(qe_ubase fp, qe_backtrace_info *info);

qe_int qe_backtrace_get_str(qe_ubase fp, char *buffer, int length);

void qe_backtrace_print(qe_ubase fp);

void qe_backtrace_call_stack_fault(qe_ubase fp, qe_backtrace_info *info);

qe_int qe_backtrace_get_str_fault(qe_ubase fp, char *buffer, int length);

void qe_backtrace_print_fault(qe_ubase fp);



#endif /* __QE_BACKTRACE_H__ */